home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ivl
/
src
/
ivl.c
< prev
next >
Wrap
Text File
|
2000-06-21
|
17KB
|
570 lines
/*
#define DEBUG
* SXアイコン表示処理(複数ファイル指定対応)
*
* ivl.x
*
* from May.29,1999. dummy.x.(with J-S.I.)
*
*謝辞: このプログラムは「電脳倶楽部」53号掲載の IV.X v1.20、および
* そのソースファイルを参照しています。
* 作者である内瀬優+頼藤凌の両氏には深く感謝いたします。
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys\dos.h>
#include "comtype.h"
#include "easymac.h"
#include "dummyc.h"
#include "hufilec.h"
#include "clinearg.h"
#include "ivl.h"
/* 定数定義 */
#define DEF_ICN_FEXT ".PT4" /* スプライトデータファイルの標準拡張子 */
#define FBITMSK_NOCTRL_ALL \
(biton(FBIT_NOCTRL_KEY) | biton(FBIT_NOCTRL_MS) | biton(FBIT_NOCTRL_JOY))
/* 操作禁止ビット全て */
/* 情報表示のみ:表示する情報 */
enum {
OI_ICON_INFO = 0, /* アイコン情報 */
OI_MAX_SIZE, /* 表示可能な画像最大サイズ */
OI_TYPE_KAZ
};
/* 大域変数 */
ushort state_flag_bits; /* 動作状態指示フラグ bit 列 */
/* ファイル内変数 */
static char prog_name[FILENAME_MAX]; /* 自己プログラム名 */
static char oi_print_info; /* 情報表示のみ:表示する情報 */
/* 使用法表示
* 引数: errf - 使用法エラー発生フラグ
* (=!0:発生した/=0:単純に使用法表示)
* 注記 * errf=0 の場合、使用法メッセージの前に作者名などを表示
* する。また、errf=!0 の場合はメッセージ表示前に1行改行する。
*/
void usage(int errf)
{
const char *msgtop;
/* 引数に応じて使用法メッセージ前の表示を切り替える */
if (errf == 0) { /* エラーでなければ */
/* 作者名とかを表示 */
msgtop = "sx-Icon Viewer ordering List extension v0.05 by dummy.x.(J-S.I.)\n"
"thanx for \'IV.X Ver1.20\'(1992-09-06 電魔団\(優)+(ら))\n";
} else { /* エラー発生時は */
/* 何も表示しない */
msgtop = "";
}
/* メッセージ表示 */
printf(
"%s\n" /* 使用法メッセージ前の表示 */
"Usage:\t%s [<options>] <icfile["DEF_ICN_FEXT"]>[ <icfile["DEF_ICN_FEXT"]>...]\n"
"Works:\tSXアイコンデータをコマンドラインでの指定順に画面表示する\n"
"\t<icfile>に拡張子がなかった場合、\""DEF_ICN_FEXT"\" を補います。\n"
"Options:\n"
/* " "CLINEARG_INDIRECT_FILE_OPT_STR"<lfile>:\n"
"\tファイル名をリストファイル <lfile> から取り出す\n"
*/ " -o[<x>][,<y>]:\n"
"\t1画面の表示アイコン数を 横<x>×縦<y> 個にする\n"
"\t(<x>: %d~%d/標準=%d / <y>: %d~%d/標準=%d)\n"
" -z[<w>][,<h>]:\n"
"\t横<w>×縦<h> dotのアイコンを表示できる表示個数を設定する\n"
"\t(<w>: %d~%d/標準=%d / <h>: %d~%d/標準=%d)\n"
/* "\t(-Z... とすると表示個数の上限判定を行なわない)\n"
*/ " -zx:\t表示アイコンの中で最大のものを表示できる表示個数を設定する\n"
/* "\t(-Zx とすると表示個数の上限判定を行なわない)\n"
*/ " -n[k][m][j]:\n"
"\t指定デバイスでの操作を禁止する(k:キーボード/m:マウス/j:ジョイスティック)\n"
" -f:\t画像データをあらかじめ読み込んでおく\n"
" -pp:\t画像情報だけを表示する\n"
" -pz:\t表示できる個数/画像サイズだけを表示する\n"
" -v:\t進行状況を表示する\n"
/* " -x:\tアイコン情報の表示を切り詰めない\n"
*/ " -?:\t簡単な使用法(このメッセージ)を表示する\n"
, msgtop, prog_name
, PAT_ON_LINE_MIN, PAT_ON_LINE_MAX, DEF_PAT_ON_LINE /* -o:<x> */
, PAT_LINE_KAZ_MIN, PAT_LINE_KAZ_MAX, DEF_PAT_LINE_KAZ /* -o:<y> */
, PAT_GRPH_W_MIN, PAT_GRPH_W_MAX, DEF_PAT_GRPH_W /* -z:<w> */
, PAT_GRPH_H_MIN, PAT_GRPH_H_MAX, DEF_PAT_GRPH_H /* -z:<h> */
);
}
/* コマンドライン文字列の処理を行なう
* 引数: argp - 引数文字列へのポインタ
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
* 使用法表示が指定されたら <0
*/
static
int chk_str_arg(const char *argp)
{
int result = 0;
struct _filbuf fbuf;
char *pathp;
/* 探索ファイル名の作成 */
pathp = malloc(strlen(argp) + 6 + 1); /* +6:"\*.PT4" */
if (pathp == NULL) {
ttlprintf("ファイル %s を検索するためのメモリが確保できませんでした。\n", argp);
#if 0
return +1; /* エラーを持って返る */
#else
return 0; /* 他に指定されたファイルを表示するのでエラーにはしない */
#endif
}
strcpy(pathp, argp);
if (is_path_only(pathp)) { /* ディレクトリ名までしか指定されていなければ */
_DEBUGJOB(printf("%s is path!\n", pathp));
append_path_separator(pathp); /* パス区切り文字と */
strcat(pathp, "*"); /* '*' を補う */
}
fcatext(pathp, DEF_ICN_FEXT);
/* パス名表示 */
printf_at_verbose(("entry \"%s\" ", pathp));
/* ファイル検索 */
if (_dos_files(&fbuf, pathp, 0x20) < 0) { /* 該当するファイルがない */
ttlprintf("ファイル %s は存在しません。\n", pathp);
#if 0
return +1; /* エラーを持って返る */
#else
return 0; /* 他に指定されたファイルを表示するのでエラーにはしない */
#endif
}
/* パス名を切り取っておく */
*fgetnamep(pathp) = '\0';
/* ファイル名登録
* ワイルドカード対応
*/
do {
int entno;
entno = entry_arg_file_name(pathp, &fbuf); /* そのファイル名を登録 */
printf_at_verbose(((entno < 0)? "x": ".")); /* '.'/'x' を打っていく */
} while (_dos_nfiles(&fbuf) >= 0); /* 該当するファイルがあるかぎり続ける */
printf_at_verbose(("\n")); /* 改行 */
free_mem(pathp);
return result;
}
/* 数字列を数値変換して、範囲内にあるかの判定も行なう
* 変換できなかったり、指定の範囲内に値がなければエラーとする
*
* 引数: valp - 変換結果格納アドレス
* strp - 被変換文字列へのポインタ
* min,max - 有効範囲の最小値/最大値
* msgp - 変換する値の内容を示す文字列へのポインタ(エラー表示で使用)
* 返値: 無事終了した場合は引数文字列の次のアドレス
* 何かエラーが発生したら NULL
* (*valp) - 変換結果
* 注記 * 変換できなかったか、変換結果が有効範囲になかった場合は
* (*valp) の値は変化しない。
*/
static
char *str_to_short(short *valp, const char *strp, short min, short max, const char *msgp)
{
char *result;
short val;
/* 変換 */
val = strtoul(strp, &result, 0);
/* 変換できないか、値が有効範囲内にない場合は指定ミス */
if ((result == strp) || (val < min) || (val > max)) {
ttlprintf("%sの指定が変です。指定できるのは %d~%d までです。\n"
, msgp, min, max);
result = NULL;
} else {
*valp = val;
}
return result;
}
/* コマンドライン '-o' オプションの引数処理を行なう
* 引数: argp - 引数文字列へのポインタ(-o の次の位置)
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
*/
static
int chk_o_option_args(const char *const argp)
{
const char *sp;
char ch;
ch = *argp;
if (ch == '\0') { /* 引数が指定されてない */
ttlprintf("o オプションの後に引数が指定されていません。\n");
return +1; /* ここでさっさと返る */
}
#if 0
clrbit_var(state_flag_bits, FBIT_PAGE_BY_SIZE); /* サイズから表示数を求めない */
/* その他の関連 bit も寝かす */
clrbit_var(state_flag_bits, FBIT_BYSZ_UNLIM); /* 個数の上限判定を行なわない */
clrbit_var(state_flag_bits, FBIT_BYSZ_FINDMX); /* 最大の画像サイズから算出 */
#else
/* サイズから表示数を求めない
* 関係 bit も寝かす
*/
state_flag_bits &= ~(biton(FBIT_PAGE_BY_SIZE)
| biton(FBIT_BYSZ_UNLIM) /* 個数の上限判定を行なわない */
| biton(FBIT_BYSZ_FINDMX)); /* 最大の画像サイズから算出 */
#endif
/* まずは横の表示数を(指定されていれば)取得 */
sp = argp;
if (*sp != ',') { /* 最初が ',' でなければ指定されている */
/* 数値変換 */
sp = str_to_short(&pat_on_line, sp
, PAT_ON_LINE_MIN, PAT_ON_LINE_MAX
, "o オプションでの横表示数");
if (sp == NULL) { /* 取得失敗 */
return +1;
}
}
/* 続いて縦の表示数を(指定されていれば)取得 */
if (*sp == ',') { /* 第1引数の後に ',' があれば指定あり */
/* 数値変換 */
sp++; /* ',' の次を指させる */
sp = str_to_short(&pat_line_kaz, sp
, PAT_LINE_KAZ_MIN, PAT_LINE_KAZ_MAX
, "o オプションでの縦表示数");
}
return (sp == NULL); /* エラーなら !0(=+1) */
}
/* コマンドライン '-z' オプションの引数処理を行なう
* 引数: argp - 引数文字列へのポインタ(-o の次の位置)
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
*/
static
int chk_z_option_args(const char *const argp)
{
short *valp;
const char *sp;
char ch;
ch = *argp;
if (ch == '\0') { /* 引数が指定されてない */
ttlprintf("z オプションの後に引数が指定されていません。\n");
return +1; /* ここでさっさと返る */
}
setbit_var(state_flag_bits, FBIT_PAGE_BY_SIZE); /* サイズから表示数を求める */
/* 特殊指定を先行判定 */
if ((ch == 'x') || (ch == 'X')) { /* 登録ファイル中の最大のものから個数算出 */
#if 0
setbit_var(state_flag_bits, FBIT_BYSZ_FINDMX); /* 最大の画像サイズから算出 */
setbit_var(state_flag_bits, FBIT_ONMEM_SZ); /* 画像サイズを先行読み込み */
#else
/* 最大の画像サイズから算出 / 画像サイズを先行読み込み */
state_flag_bits |= (biton(FBIT_BYSZ_FINDMX) | biton(FBIT_ONMEM_SZ));
#endif
return 0; /* ちゃっちゃと正常終了 */
}
/* -zx オプション定義を解除 */
#if 0
clrbit_var(state_flag_bits, FBIT_BYSZ_FINDMX); /* 最大の画像サイズから算出 */
clrbit_var(state_flag_bits, FBIT_ONMEM_SZ); /* 画像サイズを先行読み込み */
#else
state_flag_bits &= ~(biton(FBIT_BYSZ_FINDMX) | biton(FBIT_ONMEM_SZ));
#endif
/* まずは横の表示数を(指定されていれば)取得 */
valp = &pat_disp_area_w;
sp = argp;
if (*sp != ',') { /* 最初が ',' でなければ指定されている */
/* 数値変換 */
sp = str_to_short(valp, sp, PAT_GRPH_W_MIN, PAT_GRPH_W_MAX
, "z オプションでの横幅");
if (sp == NULL) { /* 取得失敗 */
return +1;
}
}
/* 続いて縦の表示数を(指定されていれば)取得 */
valp = &pat_disp_area_gh;
if (*sp == ',') { /* 第1引数の後に ',' があれば指定あり */
/* 数値変換 */
sp++; /* ',' の次を指させる */
sp = str_to_short(valp, sp, PAT_GRPH_H_MIN, PAT_GRPH_H_MAX
, "z オプションでの縦幅");
}
return (sp == NULL); /* エラーなら !0(=+1) */
}
/* コマンドライン '-n' オプションの引数処理を行なう
* 引数: argp - 引数文字列へのポインタ(-n の次の位置)
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
*/
static
int chk_n_option_args(const char *const argp)
{
int result = 0;
if (*argp == '\0') { /* "-n" だけだった */
/* 全デバイスを有効に */
state_flag_bits &= ~FBITMSK_NOCTRL_ALL;
} else { /* "-n" の後に文字がある */
int pos;
const char *ap;
/* 文字検索ループ
* 正しい文字が続くかぎり続ける
* 不正な文字にぶつかった時点で処理終了
*
* 今のところ、正しい文字が最初になかったらエラーになる
* ex) "-nking" ○(最初が'k')
* "-nokmj" ×(最初が不正文字)
*/
/* 文字検索ループ */
ap = argp;
while ((*ap != '\0') && ((pos = strindex("kmj", *ap)) >= 0)) {
state_flag_bits |= biton(pos + FBIT_NOCTRL_KEY);
ap++;
}
/* エラー判定 */
if (ap == argp) { /* 有効文字が一つもなかった */
ttlprintf("n オプションの後の文字が変です。\n");
ttlprintf("指定できるのは、\'k\'(キーボード),\'m\'(マウス),\'j\'(ジョイスティック)の3文字です。\n");
result = +1; /* 指定エラー */
}
}
return result;
}
/* コマンドライン '-p' オプションの引数処理を行なう
* 引数: argp - 引数文字列へのポインタ(-p の次の位置)
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
*/
static
int chk_p_option_args(const char *const argp)
{
int result = 0;
char ch = tolower(*argp);
setbit_var(state_flag_bits, FBIT_ONLYINFO); /* 情報表示のみで終了する */
/* 表示情報の選定 */
if (ch == 'p') { /* "-pp"...画像情報のみ */
clrbit_var(state_flag_bits, FBIT_ONMEMORY); /* 先行読み込みはさせない */
oi_print_info = OI_ICON_INFO; /* 表示情報を設定 */
} else if (ch == 'z') { /* "-pz"...表示個数/サイズのみ */
setbit_var(state_flag_bits, FBIT_NOFILE); /* ファイル名引数の処理不要 */
oi_print_info = OI_MAX_SIZE; /* 表示情報を設定 */
} else { /* "-p?"...指定ミス */
ttlprintf("%s というオプションはありません。\n", argp - 2);
result = +1; /* エラーを返す */
}
return result;
}
/* コマンドラインオプションの処理を行なう
* 引数: argp - 引数文字列へのポインタ
* 返値: 無事終了すれば 0、
* 何かエラーが発生したら >0
* 使用法表示が指定されたら <0
* 注記 * 今のところ、英文字の大小は区別しない。
* * オプション文字列の解析は、次の点で厳密でない。:
* ・オプション文字の次の1文字だけでオプションを判定する
* (-b も -bumk も同じ)。
*/
static
int chk_option_arg(const char *argp)
{
int result = 0;
/* オプション文字をチェック */
argp += 2;
switch (tolower(argp[-1])) {
case 'o': /* 表示数の指定 */
result = chk_o_option_args(argp);
break;
case 'z': /* 表示サイズの指定 */
if (*(argp - 1) == 'Z') { /* 'Z' で上限判定しない */
setbit_var(state_flag_bits, FBIT_BYSZ_UNLIM);
} else { /* 'z' で上限判定する */
clrbit_var(state_flag_bits, FBIT_BYSZ_UNLIM);
}
result = chk_z_option_args(argp);
break;
case 'n': /* 指定デバイスでの操作禁止 */
result = chk_n_option_args(argp);
break;
case 'p': /* 情報のみ表示 */
result = chk_p_option_args(argp);
break;
case 'f': /* 先行読み込み */
setbit_var(state_flag_bits, FBIT_ONMEMORY); /* 先行読み込みにする */
break;
case 'v': /* 進行状況表示 */
setbit_var(state_flag_bits, FBIT_VERBOSE);
/* fflush(stdout);
*/ setvbuf(stdout, NULL, _IONBF, 0); /* メッセージをバッファリングしない */
break;
case 'x': /* アイコン情報表示を切り詰めない */
setbit_var(state_flag_bits, FBIT_NOCUTINF);
break;
case '?': /* 使用法表示 */
result = -1; /* その旨返す */
break;
default: /* 存在しないオプション */
ttlprintf("%s というオプションはありません。\n", argp - 2);
result = +1; /* エラーを返す */
break;
}
return result;
}
/* コマンドライン検索・設定
* 引数: argv - コマンドライン単語列アドレス
* 返値: 正常に処理できれば 0、何かエラーがあれば >0
* 使用法の表示が指示されていたら <0
*/
static
int chk_argv(char **argv)
{
int result = -1; /* 引数が何もない場合の返値 */
const char *argp;
char **argpp;
++argv; /* 調べるのは argv[1] から([0] はコマンド名なので) */
/* 先行してコマンドラインオプションを調べる */
argpp = argv;
while ((argp = get_cmdline_arg(&argpp)) != NULL) {
if (is_option(argp)) { /* オプション */
result = chk_option_arg(argp);
/* エラーがあったりとか使用法表示が指定されたりとかしたら */
if (result != 0) {
return result; /* ここで即座に返ってしまう */
}
}
}
/* オプション指定全体でのエラー検査 */
/* 情報表示のみとなっていたら先行読み込みを解除 */
if (chkbit(state_flag_bits, FBIT_ONLYINFO)) {
clrbit_var(state_flag_bits, FBIT_ONMEMORY); /* 先行読み込み */
clrbit_var(state_flag_bits, FBIT_ONMEM_SZ); /* 先行サイズ読み込み */
}
/* -zx が指示されてたらファイル引数を必ず処理する */
#define FBITMSK_ZX_OPT (biton(FBIT_PAGE_BY_SIZE) | biton(FBIT_BYSZ_FINDMX))
if ((state_flag_bits & FBITMSK_ZX_OPT) == FBITMSK_ZX_OPT) {
clrbit_var(state_flag_bits, FBIT_NOFILE);
}
/* -n:ビューワ操作デバイスが全て無効 */
if (!chkbit(state_flag_bits, FBIT_ONLYINFO)
&& ((state_flag_bits & FBITMSK_NOCTRL_ALL) == FBITMSK_NOCTRL_ALL)
) {
ttlprintf("n オプションによって全ての操作デバイスが無効にされてしまいました。\n");
ttlprintf("これでは操作できないので、最低一つは操作を有効にしてください。\n");
result = +1; /* 指定エラー */
return result;
}
/* ファイル名引数は不要ならここまで */
if (chkbit(state_flag_bits, FBIT_NOFILE)) {
return result; /* さっさと返る */
}
/* 改めてファイル名引数を調べる */
argpp = argv;
while ((argp = get_cmdline_arg(&argpp)) != NULL) {
if (!is_option(argp)) { /* 文字列 */
result = chk_str_arg(argp);
/* エラーがあったりとか使用法表示が指定されたりとかしたら */
if (result != 0) {
return result; /* ここで即座に返ってしまう */
}
}
}
/* ファイル名指定全体でのエラー検査 */
if (result == 0) { /* コマンドラインには問題がなかった */
if (arg_file_kaz <= 0) { /* ファイル名が一つもテーブル登録されてない */
/* エラー扱い */
ttlprintf("表示できるファイルがありません。\n");
result = +1;
}
}
return result;
}
/* プログラムの主処理を実行する
* 返値: 無事に終了すれば 0、何か問題があったら !0
*/
static
int do_right_thing(void)
{
int result;
if (chkbit(state_flag_bits, FBIT_ONLYINFO)) { /* 情報表示のみで終了 */
if (oi_print_info == OI_ICON_INFO) { /* アイコン情報 */
result = print_all_icon_info();
} else/* if (oi_print_info == OI_MAX_SIZE)*/ { /* 表示可能な画像最大サイズ */
result = print_pageview_data();
}
} else {
result = view_icons();
}
return result;
}
/* 主処理
*/
int main(int argc, char *argv[])
{
int uke;
/* プログラム実行準備 */
get_prog_name(prog_name, argv[0]); /* プログラムタイトル抜き出し */
set_ttlprintf_values(stdout, prog_name); /* ttlprintf() に自分の名前を設定 */
/* コマンドライン引数検査 */
uke = chk_argv(argv);
if (uke != 0) { /* 何か問題があったか、ヘルプ指示されたら */
/* 使用法表示 */
usage(uke > 0);
return EXIT_FAILURE; /* エラー終了 */
}
/* 処理の実行 */
if (do_right_thing()) { /* 何か問題があったら */
return EXIT_FAILURE; /* エラー終了 */
}
/* ここまで来れば正常終了 */
return EXIT_SUCCESS;
}